package com.huawei.fakedouyin.appui;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;

import com.huawei.fakedouyin.R;
import com.huawei.fakedouyin.adapter.GridAdapter;
import com.huawei.fakedouyin.adapter.PagerSnapHelperAdapter;
import com.huawei.fakedouyin.base.BaseActivity;
import com.huawei.fakedouyin.data.ColorBean;
import com.huawei.fakedouyin.data.DmItem;
import com.huawei.fakedouyin.data.VideoInfo;
import com.huawei.fakedouyin.databinding.ActivityMainBinding;
import com.huawei.fakedouyin.manager.PlayManager;
import com.huawei.fakedouyin.util.KeyboardHeightProvider;
import com.huawei.fakedouyin.util.LiveDataSet;
import com.huawei.fakedouyin.util.LogUtil;
import com.huawei.fakedouyin.util.LogUtilKt;
import com.huawei.fakedouyin.util.MainExecutor;
import com.huawei.fakedouyin.util.SPUtil;
import com.huawei.fakedouyin.util.TimeUtil;
import com.huawei.fakedouyin.util.ViewUtil;
import com.huawei.faketaobao.constant.DMSettingText;
import com.huawei.faketaobao.constant.IConstant;
import com.huawei.faketaobao.constant.SPConstant;
import com.huawei.faketaobao.http.FakeRepository;
import com.huawei.faketaobao.http.ListResult;

import java.util.ArrayList;
import java.util.List;

import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.coroutines.EmptyCoroutineContext;

/**
 * 主界面 即视频播放界面
 */
public class MainActivity extends BaseActivity {

    private ActivityMainBinding binding;
    //视频列表滑动适配器
    private PagerSnapHelperAdapter recyclerAdapter = null;

    //弹幕颜色切换选择适配器
    private GridAdapter gridAdapter;
    //获取到的视频列表
    private ArrayList<VideoInfo> mDataList = new ArrayList<VideoInfo>();
    //弹幕颜色列表
    private List<ColorBean> colorBeanList = new ArrayList<>();
    //视频滑动帮助类 主要是使视频每次只滑动和显示一个item 达到抖音那种效果
    private PagerSnapHelper snapHelper;

    //监听键盘高度
    private KeyboardHeightProvider mKeyboardHeightProvider;
    //视频列表中 当前在显示的item的view
    private View positionView = null;

    //键盘高度的绝对值
    private int abs = 0;

    //保存的键盘高度
    private int keyHeight = SPUtil.Companion.getInstance().getInt(SPConstant.keyHeight, 700);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
        //设置状态栏颜色
        getWindow().setStatusBarColor(Color.BLACK);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        mKeyboardHeightProvider = new KeyboardHeightProvider(this);

        //视频播放后 把视频播放器显示出来
        LiveDataSet.showItem.observeForever(MainExecutor.get(), showVideoObserve);
        //自动从第一个视频开始播放的监听 第一个item初始化完成后开始播放
        LiveDataSet.zeroItemInit.observeForever(MainExecutor.get(), zeroInitObserve);
        //发送弹幕弹框view的显示和隐藏
        LiveDataSet.danmuSendView.observeForever(MainExecutor.get(), danmuViewObserve);
        LiveDataSet.SocketConnectedStatus.observeForever(MainExecutor.get(), rePlayObserve);
        //应用后台
        LiveDataSet.isBackGround.observeForever(MainExecutor.get(), backgroundObserve);
        //网络状态变化监听
        LiveDataSet.netMessage.observeForever(MainExecutor.get(), netObserve);
        //键盘高度的监听
        LiveDataSet.keyBoardHeight.observeForever(MainExecutor.get(), keyBoardObserve);
        initUI();
        initClick();
        //请求视频播放列表
        postVideos();
        //给发送弹幕界面设置高度
        ViewGroup.LayoutParams params = binding.danmuSet.getLayoutParams();
        params.height = keyHeight;
        binding.danmuSet.setLayoutParams(params);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //开始监听 获取键盘高度
                mKeyboardHeightProvider.start();
            }
        }, 500);

    }

    /**
     * 网络请求 获取视频列表
     */
    private void postVideos() {
        //初始化为false
        PlayManager.getInstance().isInit = false;
        //网络请求  获取视频列表
        new FakeRepository().getAllVideoInfoList(new Continuation<ListResult<VideoInfo>>() {
            @NonNull
            @Override
            public CoroutineContext getContext() {
                return EmptyCoroutineContext.INSTANCE;
            }

            @Override
            public void resumeWith(@NonNull Object o) {
                ListResult listResult = (ListResult) o;
                if (listResult.getCode() == IConstant.CodeSuccess) {
                    LogUtil.Companion.getInstance().logDebug("succcess");
                    mDataList.clear();
                    //存储视频列表
                    mDataList.addAll(listResult.getData());
                    MainExecutor.get().execute(() -> {
                        //刷新ui
                        recyclerAdapter.update(mDataList);
                    });

                } else {
                    LogUtil.Companion.getInstance().logDebug("not code 200");
                }
            }


        });
    }

    /**
     * 确定该视频要播放后 把video界面添加到recyclerview中显示
     *
     * @param view
     */
    private void showVideo(View view) {
        //隐藏封面图
        view.findViewById(R.id.largePicture).setVisibility(View.GONE);
        //视频播放器的容器
        RelativeLayout relativeLayout = view.findViewById(R.id.contentView);
        //把视频播放器添加进容器
        ViewUtil.removeParent(PlayManager.getInstance().getMyVideoView());
        relativeLayout.addView(PlayManager.getInstance().getMyVideoView());
    }

    /**
     * 初始化ui
     */
    public void initUI() {
        // ---RecyclerView---
        binding.recyclerView.setNestedScrollingEnabled(false);
        binding.recyclerView.setItemViewCacheSize(3);
        //布局大小固定 不重新计算
        binding.recyclerView.setHasFixedSize(true);
        // PagerSnapHelper
        snapHelper = new PagerSnapHelper() {

            // 在 Adapter的 onBindViewHolder 之后执行
            @Override
            public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
                int targetPos = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);
                LogUtil.Companion.getInstance().logDebug(targetPos + "-findTargetSnapPosition:x" + velocityX + " y:" + velocityY);
                return targetPos;
            }

            // 在 Adapter的 onBindViewHolder 之后执行
            @Nullable
            @Override
            public View findSnapView(RecyclerView.LayoutManager layoutManager) {
                //用户停止滑动后 执行此方法 判断当前是哪个item
                View view = super.findSnapView(layoutManager);
                positionView = view;
                //通过tag 找到view的下标
                int temp = Integer.parseInt(view.getTag().toString());
                LogUtilKt.logDebug("findSnapView tag: " + view.getTag());
                //停止滑动后 通过下标播放该视频
                PlayManager.getInstance().play(mDataList.get(temp));
                return view;
            }
        };
        snapHelper.attachToRecyclerView(binding.recyclerView);
        // ---布局管理器---
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        // 默认是Vertical (HORIZONTAL则为横向列表)
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        //
        binding.recyclerView.setLayoutManager(linearLayoutManager);
        recyclerAdapter = new PagerSnapHelperAdapter(mDataList, binding.recyclerView.getWidth(), binding.recyclerView.getHeight());
//                // 设置Adapter
        binding.recyclerView.setAdapter(recyclerAdapter);

        /////gridAdapter/////
        refreshColor();
        gridAdapter = new GridAdapter();
        binding.grid.setAdapter(gridAdapter);
        gridAdapter.updateData(colorBeanList);

    }

    private void initClick() {
        //发送弹幕弹框上方的遮罩 同时也是退出弹幕发送界面的监听
        binding.viewPercent30.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LogUtilKt.logDebug("viewPercent30 click");
                //隐藏输入法
                ViewUtil.HideKeyboard(binding.danmuEdit);
                //退出发送弹幕界面
                LiveDataSet.danmuSendView.postValue(false);
            }
        });

        //弹幕发送按钮
        binding.danmuSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (binding.danmuEdit.getText().toString().trim().isEmpty()) {
                    Toast.makeText(MainActivity.this, "请输入内容", Toast.LENGTH_SHORT).show();
                    binding.danmuEdit.setText("");
                } else {
                    //配置弹幕的信息
                    DmItem dmItem = new DmItem();
                    //弹幕颜色
                    dmItem.setColor(SPUtil.Companion.getInstance().getString(SPConstant.textColor, IConstant.defaultFontColor));
                    //弹幕文本消息
                    dmItem.setMsg(binding.danmuEdit.getText().toString());
                    //弹幕在视频中开始显示的时间
                    dmItem.setVideoTime(((PlayManager.getInstance().getMyVideoView().getBinding().tourVideo.getCurrentPosition() / 1000)));
                    dmItem.setPosition("置顶");
                    //弹幕的发送时间
                    dmItem.setSendTime(TimeUtil.getTime());
                    //弹幕字体大小
                    dmItem.setFontSize(SPUtil.Companion.getInstance().getInt(SPConstant.fontSize, IConstant.defaultFontSize));
                    //发送者账号
                    dmItem.setUserAccount(SPUtil.Companion.getInstance().getString(SPConstant.UserAccount, ""));
                    //视频的id
                    dmItem.setVideoId(PlayManager.getInstance().usingInfo.getVideoId());
                    //发送弹幕
                    PlayManager.getInstance().sendOneDanmu(dmItem, true);
                    //重置输入框
                    binding.danmuEdit.setText("");
                }
            }
        });

        //弹幕输入框 输入监听
        binding.danmuEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //不为空时 发送按钮显示
                if (binding.danmuEdit.getText().toString().trim().isEmpty()) {
                    binding.danmuSend.setVisibility(View.GONE);
                } else {
                    binding.danmuSend.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        //弹幕配置按钮
        binding.goneSoftInput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //显示配置界面
                binding.danmuSet.setVisibility(View.VISIBLE);
                //隐藏输入法 显示配置界面
                ViewUtil.HideKeyboard(binding.danmuEdit);
                //大于一定高度 判定当前已经弹出键盘
                if (LiveDataSet.keyBoardHeight.get()>200){
                    //隐藏输入法 显示配置界面
                    ViewUtil.HideKeyboard(binding.danmuEdit);
                }else {
                    showInputMethod();
                }
            }
        });

        //设置点击事件 防止点击事件被穿透
        binding.danmuSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });

        //弹幕字体大小 大
        binding.fontLargeLn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //改变弹幕字体大小
                changeFontSelect(true);
            }
        });

        //弹幕字体大小 小
        binding.fontSmallLn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //改变弹幕字体大小
                changeFontSelect(false);
            }
        });

        //弹幕颜色选择
        binding.grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //保存颜色
                SPUtil.Companion.getInstance().put(SPConstant.textColor, colorBeanList.get(i).getColor());
                //刷新ui
                refreshColor();
                gridAdapter.notifyDataSetChanged();
            }
        });

        //关闭弹幕按钮
        binding.danmuSwitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ViewUtil.HideKeyboard(binding.danmuEdit);
                //关闭弹幕
                LiveDataSet.danmuSwitch.postValue(false);
                //隐藏发送弹幕入口
                LiveDataSet.danmuSendView.postValue(false);
                Toast.makeText(MainActivity.this, "弹幕已关闭 可长按视频开启", Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 视频view加载完毕 显示视频view的监听
     */
    private final Observer<Boolean> showVideoObserve = n -> {
        if (n) {
            if (positionView != null) {
                //视频播放器的显示 依附于滑动的item
                showVideo(positionView);
            }
        }
    };

    /**
     * 第一次播放 view加载完成的监听
     */
    private final Observer<View> zeroInitObserve = n -> {
        LogUtil.Companion.getInstance().logDebug("zeroInitObserve view:");
        if (n != null) {
            //view加载完成后传进来并开始播放
            positionView = n;
            LogUtil.Companion.getInstance().logDebug("zeroInitObserve mDataList.size:" + mDataList.size());
            //播放第一个视频
            if (!PlayManager.getInstance().play(mDataList.get(0))) {
                Toast.makeText(this, "播放失败！", Toast.LENGTH_SHORT).show();
            }
        }
    };

    /**
     * 是否显示弹幕发送view
     */
    private final Observer<Boolean> danmuViewObserve = n -> {
        showSendDanmuView(n);
    };

    //进入后台监听
    private final Observer<Boolean> backgroundObserve = n -> {
        if (n) {

        }
    };

    /**
     * 断网恢复 重新请求并播放
     */
    private final Observer<Boolean> rePlayObserve = n -> {
        if (n) {
            //重新请求视频列表
            postVideos();
        }
    };

    /**
     * 网络监听
     */
    private final Observer<Integer> netObserve = n -> {
        if (n == 0) {
            //断网停止播放并清空
            PlayManager.getInstance().stopPlay();
            PlayManager.getInstance().usingInfo = null;
            mDataList.clear();
            recyclerAdapter.update(mDataList);
        }
    };

    /**
     * 键盘高度监听
     */
    private final Observer<Integer> keyBoardObserve = n -> {
        Log.d("KeyboardHeightProvider", "高度:" + n);
        //如果为负数  需要加上负数的绝对值
        if (n < 0) {
            abs = n;
        }
        //大于一定高度表示键盘唤起
        if (n > 50) {
            keyHeight = n;
            ViewGroup.LayoutParams params = binding.danmuSet.getLayoutParams();
            //设置弹幕发送框下方的高度 把弹幕输入框顶上去
            params.height = keyHeight + Math.abs(abs);
            MainExecutor.get().execute(() -> {
                binding.danmuSet.setLayoutParams(params);
            });
            SPUtil.Companion.getInstance().put(SPConstant.keyHeight, params.height);
        }

    };

    /**
     * 显示弹幕发送view
     *
     * @param show
     */
    private void showSendDanmuView(boolean show) {
        if (show) {
            //初始化弹幕字体大小选择
            initFontSelect();
            //刷新选择的颜色
            refreshColor();
            gridAdapter.notifyDataSetChanged();
            //弹幕配置view 先隐藏
            binding.danmuSet.setVisibility(View.INVISIBLE);
            binding.sendDanmuLayout.setVisibility(View.VISIBLE);
            //输入框获取焦点
            binding.danmuEdit.requestFocus();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    //延迟后自动唤起输入法
                    showInputMethod();
                }
            }, 50);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    binding.danmuSet.setVisibility(View.VISIBLE);
                }
            },600);
        } else {
            LogUtilKt.logDebug("hideDanmuView");
            binding.sendDanmuLayout.setVisibility(View.GONE);
        }
    }

    /**
     * 初始化弹幕字体大小选择
     */
    private void initFontSelect() {
        //读取保存的字体大小
        changeFontSelect(SPUtil.Companion.getInstance().getInt(SPConstant.fontSize, IConstant.defaultFontSize) == 0);
    }

    /**
     * 更改弹幕字体大小
     *
     * @param big
     */
    private void changeFontSelect(boolean big) {
        if (big) {
            binding.largeIcon.setImageDrawable(getDrawable(R.drawable.font_size_big_light));
            binding.largeTv.setTextColor(getColor(R.color.bili_fen));
            binding.smallIcon.setImageDrawable(getDrawable(R.drawable.font_size_small_gay));
            binding.smallTv.setTextColor(getColor(R.color.setItemColor));
        } else {
            binding.largeIcon.setImageDrawable(getDrawable(R.drawable.font_size_big_gay));
            binding.largeTv.setTextColor(getColor(R.color.setItemColor));
            binding.smallIcon.setImageDrawable(getDrawable(R.drawable.font_size_small_light));
            binding.smallTv.setTextColor(getColor(R.color.bili_fen));
        }
        //保存当前默认字体大小的选择
        SPUtil.Companion.getInstance().put(SPConstant.fontSize, big ? 0 : 1);
    }

    /**
     * 获取保存的弹幕颜色
     *
     * @return
     */
    private String getSPColor() {
        return SPUtil.Companion.getInstance().getString(SPConstant.textColor, IConstant.defaultFontColor);
    }

    /**
     * 刷新颜色选择
     */
    private void refreshColor() {
        String nowColor = getSPColor();
        if (colorBeanList.size() == 0) {
            for (int i = 0; i < DMSettingText.INSTANCE.getColorList().size(); i++) {
                String color = DMSettingText.INSTANCE.getColorList().get(i);
                ColorBean colorBean = new ColorBean(color, color.equals(getSPColor()));
                colorBeanList.add(colorBean);
            }
        } else {
            for (int i = 0; i < colorBeanList.size(); i++) {
                //被选择的颜色 状态设置为true
                if (colorBeanList.get(i).getColor().equals(nowColor)) {
                    colorBeanList.get(i).setSelect(true);
                } else {
                    colorBeanList.get(i).setSelect(false);
                }
            }
        }
    }

    /**
     * 弹起输入法
     */
    private void showInputMethod() {
        //自动弹出键盘
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        //强制隐藏Android输入法窗口
        // inputManager.hideSoftInputFromWindow(edit.getWindowToken(),0);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //恢复播放
        PlayManager.getInstance().resume(true);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //暂停播放
        PlayManager.getInstance().pause();
    }


    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //移除所有监听
        LiveDataSet.showItem.removeObserver(showVideoObserve);
        LiveDataSet.zeroItemInit.removeObserver(zeroInitObserve);
        LiveDataSet.danmuSendView.removeObserver(danmuViewObserve);
        LiveDataSet.SocketConnectedStatus.removeObserver(rePlayObserve);
        LiveDataSet.netMessage.removeObserver(netObserve);
        LiveDataSet.isBackGround.removeObserver(backgroundObserve);
        LiveDataSet.keyBoardHeight.removeObserver(keyBoardObserve);
        LiveDataSet.serviceStatus.postValue(true);
        //关闭键盘高度监听
        mKeyboardHeightProvider.close();
    }

}
